視窗應用軟體開發其中一個環節是版面設計。JUCE 有幾種控制版面的作法,本篇介紹如何使用 juce::Rectangle 類別來安排控制項。
下圖為設計目標:

首先加上必要的 TextButton。為了說明方便,程式採「作業式」寫法,在 MainComponent 加上以下三個 TextButton 物件:
  juce::TextButton google_button_;
  juce::TextButton duckduckgo_button_;
  juce::TextButton bing_button_;
接著在 MainComponent 建構式初始化上述物件,並將其加入 MainComponent:
class MainComponent  : public juce::Component
{
public:
  MainComponent() :
    google_button_("Google!"),
    duckduckgo_button_("DuckDuckGo"),
    bing_button_("Bing")
  {
    setSize (600, 400);
    addAndMakeVisible(google_button_);
    addAndMakeVisible(duckduckgo_button_);
    addAndMakeVisible(bing_button_);    
  }
};
然後替每個按鈕加上行為。在 MainComponent 建構式內,採用「作業式」複製貼上大法:
  google_button_.onClick = []()
  {
    juce::URL google("https://www.google.com");
    google.launchInDefaultBrowser();
  };
    
  duckduckgo_button_.onClick = []()
  {
    juce::URL duckduckgo("https://duckduckgo.com/");
    duckduckgo.launchInDefaultBrowser();
  };
  bing_button_.onClick = []()
  {
    juce::URL bing("https://www.bing.com/");
    bing.launchInDefaultBrowser();
  };
接下來是重頭戲,要在 MainComponent::resized 函數裡安排各個控制項的「大小」以及「位置」。本篇使用 juce::Rectangle 來切版。
首先定義兩個常數,一個表示按鈕寬度(kButtonWidth);一個表示每一行之間的間隔(kRowDistance)。
getLocalBounds 函數回傳 Rectangle,代表 MainComponent 的可用大小,接著呼叫 reduced 函數,將上下左右分別內縮 (20, 10)。
取得內縮後的 Rectangle 後,利用 removeFromTop 函數取得整個 MainComponent 高度的 20%。
void MainComponent::resized()
{
  const int kButtonWidth = 150;
  const int kRowDistance = 10;
  const int kButtonDistance = 20;
  auto bounds = getLocalBounds().reduced(20, 10);
  auto first_row = bounds.removeFromTop(getLocalBounds().getHeight() * 0.2);
}
取得第一列的 Rectangle 後,開始切三個按鈕的位置。
void MainComponent::resized()
{
  auto google_bounds = first_row.removeFromLeft(kButtonWidth);
  google_button_.setBounds(google_bounds);
  
  first_row.removeFromLeft(kButtonDistance);
  auto duckduckgo_bounds = first_row.removeFromLeft(kButtonWidth);
  duckduckgo_button_.setBounds(duckduckgo_bounds);
  
  first_row.removeFromLeft(kButtonDistance);
  auto bing_bounds = first_row.removeFromLeft(kButtonWidth);
  bing_button_.setBounds(bing_bounds);
}
到目前為止,離我們的設計目標還有點距離,需要進一步調整。

juce::Rectangle 的詳細用法,我建議閱讀以下兩篇: